/*
 * $Id$
 */
package py.firefly.request;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import py.firefly.Handler;
import py.firefly.Route;

import static py.firefly.request.HttpMethod.*;

/**
 *
 * @author myang
 */
public class DefaultRequestMapper implements RequestMapper {

    private List<RouteEntry> _gets;

    private List<RouteEntry> _posts;

    private DefaultRequestMapper() {
        _gets = new ArrayList();
        _posts = new ArrayList();
    }

    public static RequestMapper of(final Route... routes) {
        final DefaultRequestMapper m = new DefaultRequestMapper();
        return m.add(routes);
    }

    /**
     * 
     * @param req
     * @param defaultHandler
     * @return 
     */
    @Override
    public Handler map(final Request req) {
        final List<RouteEntry> entries = 
          req.is(GET) ? _gets : (req.is(POST) ? _posts : Collections.EMPTY_LIST);
        return map(entries, req);
    }

    /**
     * 
     * @param m
     * @param req
     * @return 
     */
    private static Handler map(final List<RouteEntry> entries, 
                                         final Request req) {
        final String uri = req.uri();
        for (final RouteEntry e : entries) {
            final List<PathParameter> pp = e._uriTemplate.params();
            if (0 == pp.size()) {
                if (e._path.equals(uri)) {
                    return e._handler;
                }
            }
            else if (uri.startsWith(e._path)) {
                req.params().add(e._uriTemplate.parse(uri));
                return e._handler;
            }
        }
        return null;
    }

    @Override
    public RequestMapper add(final Route... routes) {
        for (final Route r : routes) {
            final SimpleUriTemplate t = new SimpleUriTemplate(r.path());
            final RouteEntry e = new RouteEntry(t.path(), t, r.handler());
            if (r.accepts(GET)) {
                _gets.add(e);
            }
            else if (r.accepts(POST)) {
                _posts.add(e);
            }
        }
        return this;
    }

    private static class RouteEntry {
        String _path;
        SimpleUriTemplate _uriTemplate;
        Handler _handler;
        RouteEntry(final String p, final SimpleUriTemplate t, final Handler h) {
            _path = p;
            _uriTemplate = t;
            _handler = h;
        }
    }
    
}
